# 引入PyAnyCAD包
from AnyCAD import PyAnyCAD as AnyCAD
from AnyCAD.PyAnyView import IRenderControl
from Framework import TestFramework
import math


class TestBottle(TestFramework.TestCase):
    def __init__(self):
        super().__init__("Modeling","Bottle")

    def Run(self, renderView:IRenderControl):
        # 创建一个瓶子
        w = 50
        h = 70
        t = 30
        p0 = AnyCAD.GPnt(-w / 2.0, 0.0, 0.0)
        p1 = AnyCAD.GPnt(-w / 2.0, -t / 4.0, 0.0)
        p2 = AnyCAD.GPnt(0.0, -t / 2.0, 0.0)
        p3 = AnyCAD.GPnt(w / 2.0, -t / 4.0, 0.0)
        p4 = AnyCAD.GPnt(w / 2.0, 0.0, 0.0)
        
        seg0 = AnyCAD.CurveBuilder.MakeLine(p0, p1)
        arc = AnyCAD.CurveBuilder.MakeArcOfCircle(p1, p3, p2)
        seg1 = AnyCAD.CurveBuilder.MakeLine(p3, p4)
        
        edges = AnyCAD.TopoShapeList()
        edges.push_back(seg0)
        edges.push_back(arc)
        edges.push_back(seg1)
        wire = AnyCAD.CurveBuilder.ConnectToWires(edges, 0.1, False)
        
        color = AnyCAD.Vector3(0.6, 0.6, 0.6)
        belowPart = wire[0]
        abovePart = AnyCAD.TransformTool.MirrorByPoint(belowPart, AnyCAD.GPnt(0, 0, 0))
        
        edges = AnyCAD.TopoShapeList()
        edges.push_back(belowPart)
        edges.push_back(abovePart)
        wireBases = AnyCAD.CurveBuilder.ConnectWiresToWires(edges, 0.1, False)
        wireBase = wireBases[0]
        
        baseFace = AnyCAD.CurveBuilder.MakePlanarFace(wireBase)
        body = AnyCAD.FeatureTool.Extrude(baseFace, h, AnyCAD.GDir(0, 0, 1))
        body = AnyCAD.FeatureTool.Fillet(body, t / 12.0)
        
        axis = AnyCAD.GAx2(AnyCAD.GPnt(0, 0, h), AnyCAD.GDir(0, 0, 1))
        neck = AnyCAD.ShapeBuilder.MakeCylinder(axis, t / 4.0, h / 10.0, math.pi * 2)
        
        body = AnyCAD.BooleanTool.Fuse(body, neck)
        
        zMax = -1.0
        removeIndex = -1
        children = body.GetChildren(AnyCAD.EnumTopoShapeType_Topo_FACE)
        for child in children:
            ps = AnyCAD.ParametricSurface(child)
            if ps.GetSurfaceType() == AnyCAD.EnumSurfaceType_SurfaceType_Plane:
                plane = ps.TryPlane()
                z = plane.Location().Z()
                if z > zMax:
                    zMax = z
                    removeIndex = body.FindChildIndex(child)
        removeIndexList = AnyCAD.Int32List()
        removeIndexList.push_back(removeIndex)
        body = AnyCAD.FeatureTool.Thickness(body, -t / 50.0, removeIndexList)
            
            
        neckRadius = t / 4.0
        neckHeight = h / 10.0
        # Threading : Create Surfaces
        
        neckAx2 = axis
            
        
        circleInner = AnyCAD.CurveBuilder.MakeCircle(neckAx2, neckRadius * 0.99)
        circleOutter = AnyCAD.CurveBuilder.MakeCircle(neckAx2, neckRadius * 1.05)
        
        cylindricalSurfaceInner = AnyCAD.FeatureTool.Extrude(circleInner, neckHeight, AnyCAD.GDir(0, 0, 1))
        cylindricalSurfaceOutter = AnyCAD.FeatureTool.Extrude(circleOutter, neckHeight, AnyCAD.GDir(0, 0, 1))
        
        # Threading : Define 2D Curves
        center = AnyCAD.GPnt2d(2.0 * math.pi, -neckHeight / 2.0)
        dir = AnyCAD.GDir2d(2.0 * math.pi, neckHeight / 4.0)
        ax2d = AnyCAD.GAx2d(center, dir)
        
        major = 2.0 * math.pi
        minor = neckHeight / 10
        arc1 = AnyCAD.Curve2dBuilder.MakeElipsArc(AnyCAD.GElips2d(ax2d, major, minor), 0, math.pi)
        arc2 = AnyCAD.Curve2dBuilder.MakeElipsArc(AnyCAD.GElips2d(ax2d, major, minor / 4.0), 0, math.pi)
        s = AnyCAD.GPnt2d(center.XY().Subtracted(dir.XY().Multiplied(major)))
        e = AnyCAD.GPnt2d(center.XY().Added(dir.XY().Multiplied(major)))
        line = AnyCAD.Curve2dBuilder.MakeLine(s, e)
        
        
        # Threading : Build Edges and Wires
        arcOnInner = AnyCAD.CurveBuilder.MakeCurveOnSurface(arc1, cylindricalSurfaceInner)
        lineOnInner = AnyCAD.CurveBuilder.MakeCurveOnSurface(line, cylindricalSurfaceInner)
        arcOnOutter = AnyCAD.CurveBuilder.MakeCurveOnSurface(arc2, cylindricalSurfaceOutter)
        lineOnOutter = AnyCAD.CurveBuilder.MakeCurveOnSurface(line, cylindricalSurfaceOutter)
        threadingInner = AnyCAD.CurveBuilder.MakeWire(arcOnInner, lineOnInner)
        threadingOutter = AnyCAD.CurveBuilder.MakeWire(arcOnOutter, lineOnOutter)
        
        threadingList = AnyCAD.TopoShapeList()
        threadingList.push_back(threadingInner)
        threadingList.push_back(threadingOutter)
        threading = AnyCAD.FeatureTool.Loft(threadingList, True, False)
        
        renderView.ShowTopoShape(threading, None)
        renderView.ShowTopoShape(body, None) 

TestFramework.TestSuit.Add(TestBottle())